
import { Ref } from "vue";
import storage from '@/utils/storage'

/**
 * websockets 封装类
 */
class Sockets {
  timer: any; // 定时器用于 ping 防止掉线
  errTimer: any; // 错误的重连
  url: string; // 连接地址
  isOnline: Ref<boolean>; // 是否连接
  socket?: WebSocket; // socket实类
  reconnectTime: number; // 断线重连次数
  isOpenReconnect: boolean; // 是否开启重连，主动断线则不开启
  lockReconnect: boolean; // 断开关闭和错误都会执行，故添加参数只执行一个
  callbackMessage: Function
  userId: string
  constructor(callback: Function) {
    this.timer = null;
    this.url = import.meta.env.VITE_BASE_SOCKET_API
    this.callbackMessage = callback
    this.isOnline = ref(false);
    this.socket = undefined;
    this.reconnectTime = 0;
    this.isOpenReconnect = true;
    this.lockReconnect = true; // 防止error 和onclose同时链接，导致重连多次
    // 获取当前用户相关信息
    let userId = storage.get('userIdQs', false) as string
    console.log(userId)
    if (!userId) {
      userId = new Date().getTime().toString() + Math.floor(Math.random() * 1000).toString() as string
      storage.set('userIdQs', userId)
    }
    this.userId = userId
    this.connectSocket()
  }
  connectSocket() {
    const url = this.url + '/' + this.userId

    this.socket = new WebSocket(url);
    // 监听连接成功
    this.socket.onopen = () => this.onOpen()
    // 监听接收信息
    this.socket.onmessage = (e) => this.onMessage(e);
    // 监听断开
    this.socket.onclose = (e) => this.onClose(e);
    // 监听错误
    this.socket.onerror = (e) => this.onError(e);
  }
  onOpen() {
    // 用户上线
    this.isOnline.value = true;
    console.log("websocket连接成功");
    this.isOpenReconnect = true;
    if (this.socket != null) {
      // 心跳，防止断线 每100秒发送一次
      this.timer = setInterval(() => {
        console.log("发送心跳");


        this.send({ type: "ping" });
        //里面执行的操作

        //里面执行的操作
      }, 20000);
    }
  }

  onClose(e) {
    console.log(e);
    console.log("连接错误");

    if (this.lockReconnect) {
      clearInterval(this.timer);
      this.timer = null;
      this.lockReconnect = false;
      // 用户下线
      this.isOnline.value = false;
      this.socket = undefined;
      console.log("socket连接已关闭");
      if (this.isOpenReconnect) {
        console.log("3秒后重新链接");
        var that = this;
        this.errTimer = setTimeout(function () {
          that.reconnect();
          that.lockReconnect = true;
        }, 3000);
      }
    }
  }
  onMessage(data) {

    const datas = JSON.parse(data.data)
    this.callbackMessage(datas)
  }
  // 监听连接错误
  onError(e) {
    console.log(e)
    if (this.lockReconnect) {
      clearInterval(this.timer);
      this.timer = null;
      this.lockReconnect = false;
      // 用户下线
      this.isOnline.value = false;
      this.socket = undefined;
      console.log("socket连接错误");
      if (!this.socket) {
        var that = this;
        this.errTimer = setTimeout(function () {
          that.reconnect();
          that.lockReconnect = true;
        }, 3000);
      }
    }
  }
  // 断线重连
  reconnect() {
    if (this.isOnline.value) {
      return;
    }
    if (this.reconnectTime >= 3) {
      return this.reconnectConfirm();
    }
    this.reconnectTime += 1;
    console.log("重新链接第" + this.reconnectTime + "次");
    this.connectSocket();
  }
  // 断线重连提示
  reconnectConfirm() {
    console.log("链接失败，已经停止重连");

    this.connectSocket();
    this.reconnectTime = 0;
  }
  close() {
    if (this.socket) {
      clearInterval(this.timer);
      this.timer = null;
      clearInterval(this.errTimer);
      this.errTimer = null;

      this.socket.close({});
    }
    this.destoryChatObject();
    this.isOpenReconnect = false;
    console.log(this.isOpenReconnect + "关闭了");
  }
  send(params: any) {
    this.socket?.send(JSON.stringify(params));
  }
  sendFile(data: any) {
    this.socket?.send(data);
  }
  // 销毁聊天对象
  destoryChatObject() {
    this.TO = undefined;
  }
}
export default Sockets
